let fs = require('fs');
let debug = require('debug')('file2oss:dir2oss');
let path = require('path');
let oss = require('./oss');
let m = require('moment');
let fileinfo = require('./file2oss');
let events = require('events');
let util = require('./util');
let serve = require('async');

module.exports = class dir2oss extends events.EventEmitter {
    constructor(ossClient, opts) {
        super();
        if (!ossClient || !(ossClient instanceof oss)) {
            throw '请选择OSSClient';
        }

        this.OSS = ossClient;
        this.options = Object.assign({
            lockfile: '1.lock',
            directory: '',
        }, opts);
    }

    /**
     * 开始上传整个目录
     * @return {Promise<void>}
     */
    async start() {
        await  this.sendDir();
    }

    /**
     * 上传目录
     * @param relpath 相对目录
     */
    sendDir(relpath = '') {

        let callback = util.createPromiseCallback();
        let that = this;
        if (this.isLock(relpath)) {
            callback();

        } else {

            function done() {
                let files = fs.readdirSync(path.join(this.options.directory, relpath), {withFileTypes: true});
                serve.eachSeries(files, function(file, cb) {
                    if (file.isDirectory()) {
                        that.sendDir(path.join(relpath, file.name)).then(cb);
                    } else {
                        if (!file.isFile()) {
                            debug(path.join(this.options.directory, relpath, file.name), ' not file !');
                            cb();
                            return;
                        }
                        that.sendFile(path.join(relpath, file.name)).then(function(rts) {
                            cb();
                        }, function(err) {
                            cb();
                        });
                    }

                }, callback);
            }

            let cb = done.bind(this);
            if (!this.emit('begin read', relpath, cb)) {
                cb();
            }
        }
        return callback.promise;
    }

    /**
     * 上传文件
     * @param relpath 文件相对路径
     * @return {Promise<any> | *}
     */
    sendFile(relpath) {
        let file = new fileinfo(this.OSS, {directory: this.options.directory, relpath});
        let that = this;
        let callback = util.createPromiseCallback();

        function done() {
           debug('begin send file:', file.file.relpath);
            file.send().then(function(rts) {
                if (!that.emit('end send', rts, file, callback)) {
                    callback(null, rts);
                }
            }, function(rts) {
                if (!that.emit('error send', rts, file, callback)) {
                    callback(rts);
                }

            });
        }

        let cb = done.bind(this);
        if (!this.emit('begin send', file, cb)) {
            cb();
        }
        return callback.promise;
    }

    /**
     * 文件夹是否锁定
     * @param reldirpath
     * @return {boolean}
     */
    isLock(reldirpath) {
        try {
            let content = fs.readFileSync(path.join(this.options.directory, reldirpath, this.options.lockfile), {encoding: 'utf8'});
            return content !== 'false';
        } catch (e) {
            return false;
        }
    }

};

